// 68K CPU interface

#include "shared.h"
#include "types.h"
#include "cpu68k.h"

int m68k_int_ack_callback(int int_level);
/********************************************/

#define AURA_MAP

	struct M68K_CONTEXT cpu_contxt;
	struct M68K_PROGRAM prg_fetch[] =
	{
		{ 0x000000, 0x3FFFFF, (unsigned)cart_rom },
		{ 0xFF0000, 0xFFFFFF, (unsigned)(work_ram - 0xFF0000) },
#ifdef AURA_MAP
		{ 0xF00000, 0xF0FFFF, (unsigned)(work_ram - 0xF00000) },
		{ 0xEF0000, 0xEFFFFF, (unsigned)(work_ram - 0xEF0000) },
#endif
		{ -1, -1, (unsigned)NULL }
	};

	struct M68K_DATA data_rb[] = {
#ifdef AURA_MAP
		{ 0x000000, 0x3FFFFF, NULL, cart_rom },
		{ 0xA00000, 0xAFFFFF, (void *)mem68k_read_io_8, NULL },
		{ 0xC00000, 0xDFFFFF, (void *)mem68k_read_vdp_8, NULL },
		{ 0xFF0000, 0xFFFFFF, NULL, (work_ram - 0xFF0000) },
#elif defined MY_MAP
		{ 0x000000, 0x3FFFFF, NULL, cart_rom },         // cartridge area
		{ 0x400000, 0xA1FFFF, m68k_read_memory_8, NULL },
//		{ 0xA10000, 0xA1FFFF, mem68k_read_io_8, NULL },    // IO area
		{ 0xC00000, 0xC00FFF, mem68k_read_vdp_8, NULL},    // VDP area
		{ 0xFF0000, 0xFFFFFF, m68k_read_memory_8,NULL },
#else
		{ 0x000000, 0xFFFFFF, m68k_read_memory_8, NULL },
#endif
		{ -1, -1, NULL, NULL }
	};

	struct M68K_DATA data_rw[] = {
#ifdef AURA_MAP
		{ 0x000000, 0x3FFFFF, NULL, cart_rom },
		{ 0xA00000, 0xAFFFFF, (void *)mem68k_read_io_16, NULL },
		{ 0xC00000, 0xDFFFFF, (void *)mem68k_read_vdp_16, NULL },
		{ 0xFF0000, 0xFFFFFF, NULL, (work_ram - 0xFF0000) },
#elif defined MY_MAP
		{ 0x000000, 0x3FFFFF, NULL, cart_rom },
		{ 0x400000, 0xA1FFFF, m68k_read_memory_16, NULL },
		{ 0xC00000, 0xC00FFF, mem68k_read_vdp_16, NULL},    // VDP area
		{ 0xFF0000, 0xFFFFFF, m68k_read_memory_16, NULL },
#else
		{ 0x000000, 0xFFFFFF, m68k_read_memory_16, NULL },
#endif
		{ -1, -1, NULL, NULL }
	};

	struct M68K_DATA data_wb[] = {
#ifdef AURA_MAP
		{ 0x000000, 0x3FFFFF, NULL, cart_rom },
		{ 0xA00000, 0xAFFFFF, (void *)mem68k_write_io_8, NULL },
		{ 0xC00000, 0xDFFFFF, (void *)mem68k_write_vdp_8, NULL },
		{ 0xFF0000, 0xFFFFFF, NULL, (work_ram - 0xFF0000) },
#elif defined MY_MAP
		{ 0x000000, 0xA1FFFF, m68k_write_memory_8, NULL },
//		{ 0xA10000, 0xA1FFFF, mem68k_write_io_8, NULL },    // IO AREA
		{ 0xC00000, 0xC00FFF, mem68k_write_vdp_16, NULL},    // VDP area
		{ 0xFF0000, 0xFFFFFF, m68k_write_memory_8, NULL },

#else
		{ 0x000000, 0xFFFFFF, m68k_write_memory_8, NULL },
#endif
		{ -1, -1, NULL, NULL }
	};

	struct M68K_DATA data_ww[] = {
#ifdef AURA_MAP
		{ 0x000000, 0x3FFFFF, NULL, cart_rom },
		{ 0xA00000, 0xAFFFFF, (void *)mem68k_write_io_16, NULL },
		{ 0xC00000, 0xDFFFFF, (void *)mem68k_write_vdp_16, NULL },
		{ 0xFF0000, 0xFFFFFF, NULL, (work_ram - 0xFF0000) },
#elif defined MY_MAP
#error MYMAP
		{ 0x000000, 0xA1FFFF, m68k_write_memory_16, NULL },
//		{ 0xA10000, 0xA1FFFF, mem68k_write_io_16, NULL },    // IO AREA
		{ 0xC00000, 0xC00FFF, mem68k_write_vdp_16, NULL},    // VDP area
//		{ 0xFF0000, 0xFFFFFF, NULL, work_ram - 0xFF0000 },
		{ 0xFF0000, 0xFFFFFF, m68k_write_memory_16, NULL },

#else
#error OTHERMAP
		{ 0x000000, 0xFFFFFF, m68k_write_memory_16, NULL },
#endif
		{ -1, -1, NULL, NULL }
	};

/********************************************/

void M68K_Init(int cpu68k_type)
{
  switch(cpu68k_type)
  {
    case 0:
      // C68K
      C68k_Init(&C68K, m68k_int_ack_callback);

      C68k_Set_ReadB(&C68K, m68k_read_memory_8);
      C68k_Set_ReadW(&C68K, m68k_read_memory_16);

      C68k_Set_WriteB(&C68K, m68k_write_memory_8);
      C68k_Set_WriteW(&C68K, m68k_write_memory_16);

      C68k_Set_Fetch(&C68K, 0x000000, 0x3FFFFF, (u32) cart_rom);
      C68k_Set_Fetch(&C68K, 0xFF0000, 0xFFFFFF, (u32) work_ram);

      C68k_Reset(&C68K);
      break;

    case 1:
      // Fame
      memset(&cpu_contxt,0,sizeof(cpu_contxt));

      cpu_contxt.sv_fetch = prg_fetch;
      cpu_contxt.user_fetch = prg_fetch;
      cpu_contxt.sv_read_byte = data_rb;
      cpu_contxt.user_read_byte = data_rb;
      cpu_contxt.sv_read_word = data_rw;
      cpu_contxt.user_read_word = data_rw;
      cpu_contxt.sv_write_byte = data_wb;
      cpu_contxt.user_write_byte = data_wb;
      cpu_contxt.sv_write_word = data_ww;
      cpu_contxt.user_write_word = data_ww;
      cpu_contxt.iack_handler = (void (*)(unsigned)) m68k_int_ack_callback;
      m68k_set_context(&cpu_contxt);
      m68k_init();
      break;

    #ifdef CPU68K_USE_MUSASHI
    case 2:
      //MUSASHI
      m68k_set_cpu_type(M68K_CPU_TYPE_68000);
      m68k_pulse_reset();
      m68k_set_int_ack_callback(m68k_int_ack_callback);
      break;
    #endif
  }
}

